#include "airmidwvudp.h"

AirMidWVUdp::AirMidWVUdp(QObject *parent) : UdpBase(parent)
{

}

void AirMidWVUdp::startProcess()
{
    m_runStatus = true;
}

void AirMidWVUdp::stopProcess()
{
    m_runStatus = false;
}

void AirMidWVUdp::setTargetFps(int fps)
{

}

void AirMidWVUdp::onInitUdp()
{
    m_udpReceive = new QUdpSocket(this);

    QNetworkInterface netInterface = getNetInterface(m_bindIP);

    //windows上必须绑定AnyIPv4不然就会绑定失败,linux可以绑定具体的组播ip
    bool isOK = m_udpReceive->bind(QHostAddress::AnyIPv4, m_bindPort, QUdpSocket::ShareAddress);

    if(isOK == false){
        qDebug()<<QString("组播bind失败%1 %2").arg(m_bindIP).arg(m_bindPort);
        return;
    }

    isOK = m_udpReceive->joinMulticastGroup(QHostAddress(m_bindIP), netInterface);
    if(isOK == false){
        qDebug()<<QString("组播jion失败%1").arg(m_bindIP);
        return;
    }

    qDebug() << "组播成功:" << m_bindIP << ":" << m_bindPort;
    connect(m_udpReceive, &QUdpSocket::readyRead, this, &AirMidWVUdp::onReceive);
}

void AirMidWVUdp::onReceive()
{
    while (m_udpReceive->hasPendingDatagrams()) {

        //如果状态设置是停止，即false
        if(!m_runStatus) {
            continue;
        }

        QNetworkDatagram datagram = m_udpReceive->receiveDatagram();

        //如果是广播方式，在多网卡情况下，需要获取当前绑定网卡的index，来和收到的网卡的index对比，如果
        //不一致则舍弃，避免重复接收
         if(datagram.interfaceIndex() != static_cast<uint>(m_netCardIndex)) {
             continue;
         }

        QString srcIp = datagram.senderAddress().toString().section(":", -1);
        //quint16 srcPort = static_cast<quint16>(datagram.senderPort());

        if(srcIp != m_srcIP || datagram.data().size() <= 8) {
            continue;
        }

        processSlice(datagram.data());
    }
}

void AirMidWVUdp::processSlice(const QByteArray &data)
{
    // 检查帧头是否为0x49 0x52 0x31 0x36
    if (data.size() < 4 ||
        static_cast<quint8>(data[0]) != 0x49 ||
        static_cast<quint8>(data[1]) != 0x52 ||
        static_cast<quint8>(data[2]) != 0x31 ||
        static_cast<quint8>(data[3]) != 0x36) {
        qWarning() << "收到无效数据包，帧头不匹配";
        return;
    }

    // 检查数据包总大小是否为1312字节
    if (data.size() != 1312) {
        qWarning() << "数据包大小错误，实际大小:" << data.size() << "预期:1312";
        return;
    }

    // 解析照片帧号（4字节，小端模式）
    quint32 frameNumber = qFromLittleEndian<quint32>(reinterpret_cast<const uchar*>(data.constData() + 4));

    // 解析切片帧号（4字节，小端模式）
    quint32 sliceNumber = qFromLittleEndian<quint32>(reinterpret_cast<const uchar*>(data.constData() + 8));

    // 解析切片大小（4字节，小端模式）,暂不需要
    //quint32 sliceSize = qFromLittleEndian<quint32>(reinterpret_cast<const uchar*>(data.constData() + 12));


    QByteArray imageSlice = data.mid(32, 1280);  // 从32字节偏移开始，提取1280字节图片数据

    // 获取或创建当前帧的FrameData对象
    m_frame.frameNumber = frameNumber;

    //如果有丢行情况，直接清除这一帧
    if (sliceNumber == 0 && m_frame.slices.size() > 0) {
        m_frame.slices.clear();
    }

    // 存储当前切片数据
    m_frame.slices[sliceNumber] = imageSlice;

    // 情况二 如果没有丢片的情况下，检查是否已收到所有切片512
    if (m_frame.slices.size() == m_totalSlices) {
        // 按切片号顺序拼接所有图片数据
        QByteArray completeImageData;
        for (quint16 i = 0; i < m_totalSlices; ++i) {
            completeImageData.append(m_frame.slices[i]);
        }

        emit sigToEncodeImg(completeImageData);
        //qDebug() << "一帧的size" << completeImageData.size() << "frame.size()" << m_frame.slices.size();
        m_frame.slices.clear();
    }
}
